package com.nnnu.wsnackshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nnnu.wsnackshop.config.JwtRealm;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.RolesMapper;
import com.nnnu.wsnackshop.mapper.UsersMapper;
import com.nnnu.wsnackshop.pojo.dto.AssignUserRoleDTO;
import com.nnnu.wsnackshop.pojo.entity.Roles;
import com.nnnu.wsnackshop.pojo.entity.UserRoles;
import com.nnnu.wsnackshop.mapper.UserRolesMapper;
import com.nnnu.wsnackshop.pojo.entity.Users;
import com.nnnu.wsnackshop.pojo.vo.RoleVO;
import com.nnnu.wsnackshop.pojo.vo.UserRoleVO;
import com.nnnu.wsnackshop.service.IUserRolesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户-角色关联 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@RequiredArgsConstructor
public class UserRolesServiceImpl extends ServiceImpl<UserRolesMapper, UserRoles> implements IUserRolesService {

    private final UsersMapper userMapper;
    private final RolesMapper roleMapper;
    private final JwtRealm jwtRealm; // 用于清授权缓存

    @Override
    public UserRoleVO getUserRoles(Long userId) {
        // 校验用户存在
        if (userMapper.selectById(userId) == null) {
            throw new ObjectException("用户不存在: " + userId);
        }
        Set<Long> roleIds = roleMapper.selectRoleIdsByUserId(userId);
        Set<String> roleNames = roleMapper.selectRoleNamesByUserId(userId);

        UserRoleVO vo = new UserRoleVO();
        vo.setUserId(userId);
        vo.setRoleIds(roleIds);
        vo.setRoleNames(roleNames);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignRoles(@NotNull AssignUserRoleDTO dto) {
        Long userId = dto.getUserId();
        Set<Long> roleIds = dto.getRoleIds();

        // 1. 校验用户存在
        Users user = userMapper.selectById(userId);
        if (user == null) {
            throw new ObjectException("用户不存在: " + userId);
        }
        // 2. 校验所有角色 ID 都存在
        Set<Long> bad = roleIds.stream().distinct().filter(rid -> roleMapper.selectById(rid) == null).collect(Collectors.toSet());
        if (!bad.isEmpty()) {
            throw new ObjectException("以下角色不存在: " + bad);
        }
        // 3. 删除旧关联
        baseMapper.delete(new LambdaUpdateWrapper<UserRoles>().eq(UserRoles::getUserId, userId));
        // 4. 批量插入新关联
        roleIds.forEach(rid -> baseMapper.insert(new UserRoles().setUserId(Math.toIntExact(userId)).setRoleId(Math.toIntExact(rid))));
        // 5. 清除该用户授权缓存，立即生效
        jwtRealm.clearCache(SecurityUtils.getSubject().getPrincipals());
    }

    @Override
    public List<RoleVO> listRoles() {
        // 用 Shiro 判断当前用户是否是 superAdmin
        Subject subject = SecurityUtils.getSubject();
        List<Roles> roles;
        if (subject.hasRole("superAdmin")) {
            // 超管：查询所有
            roles = roleMapper.selectList(null);
        } else {
            LambdaQueryWrapper<Roles> qw = Wrappers.<Roles>lambdaQuery().ne(Roles::getName, "superAdmin").ne(Roles::getName, "admin");
            roles = roleMapper.selectList(qw);
        }
        return roles.stream().map(r -> {
            RoleVO vo = new RoleVO();
            BeanUtil.copyProperties(r, vo);
            return vo;
        }).collect(Collectors.toList());
    }
}
